package sy.service;

import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Files;
import org.nutz.lang.Strings;
import org.nutz.mapl.Mapl;

import sy.po.Company;
import sy.po.MethodLog;
import sy.po.Resource;
import sy.po.Role;
import sy.po.User;
import sy.util.BeanUtil;

/**
 * 
 * 初始化数据库服务类
 * 
 * @author 孙宇
 *
 */
@IocBean(name = "initDataBaseService")
public class InitDataBaseService {

	@Inject("refer:dao")
	private Dao dao;

	// aop拦截器的作用是开启事物，只要方法上写上@Aop({ "transactionInterceptor" })，就可以在方法执行前开启事物，方法执行结束关闭事物，查询数据库的方法不用写这个注解，避免开启事物影响速度
	@Aop({ "transactionInterceptor" })
	public void initDataBase() {

		String json = Files.read("defaultDb.js");// 找到默认数据表信息的文件
		Object db = Json.fromJson(json);

		Boolean dropIfExists = (Boolean) Mapl.maplistToObj(Mapl.cell(db, "dropIfExists"), Boolean.class);// 是否删除表结构

		dao.create(User.class, dropIfExists);// 创建用户表
		dao.create(Company.class, dropIfExists);// 创建公司表
		dao.create(Role.class, dropIfExists);// 创建角色表
		dao.create(MethodLog.class, dropIfExists);// 创建方法日志表
		dao.create(Resource.class, dropIfExists);// 创建资源表

		// 恢复公司数据
		List<?> companys = (List<?>) Mapl.maplistToObj(Mapl.cell(db, "companys"), List.class);
		for (int i = 0; i < companys.size(); i++) {
			Company t = (Company) Mapl.maplistToObj(companys.get(i), Company.class);
			Company o = dao.fetch(t);
			if (o == null) {
				dao.insert(t);
			} else {
				BeanUtil.copyNotNullProperties(t, o);
				dao.update(o);
			}
		}

		// 恢复资源数据
		List<?> resources = (List<?>) Mapl.maplistToObj(Mapl.cell(db, "resources"), List.class);
		for (int i = 0; i < resources.size(); i++) {
			Resource t = (Resource) Mapl.maplistToObj(resources.get(i), Resource.class);
			Resource o = dao.fetch(t);
			if (o == null) {
				dao.insert(t);
			} else {
				BeanUtil.copyProperties(t, o);
				dao.update(o);
			}
		}

		// 恢复角色数据
		List<?> roles = (List<?>) Mapl.maplistToObj(Mapl.cell(db, "roles"), List.class);
		for (int i = 0; i < roles.size(); i++) {
			Role t = (Role) Mapl.maplistToObj(roles.get(i), Role.class);
			Role o = dao.fetch(t);
			if (o == null) {
				dao.insert(t);
			} else {
				BeanUtil.copyNotNullProperties(t, o);
				dao.update(o);
			}
		}

		// 恢复用户数据
		List<?> users = (List<?>) Mapl.maplistToObj(Mapl.cell(db, "users"), List.class);
		for (int i = 0; i < users.size(); i++) {
			User t = (User) Mapl.maplistToObj(users.get(i), User.class);
			String pwd = (String) Mapl.cell(db, "users[" + i + "].pwd");
			t.setPwd(DigestUtils.sha1Hex(pwd));// 加密密码
			User o = dao.fetch(t);
			if (o == null) {
				o = dao.insert(t);
			} else {
				BeanUtil.copyNotNullProperties(t, o);
				dao.update(o);
			}

			dao.clearLinks(o, "roles");// 清空用户中的角色关联
			String roleIds = (String) Mapl.cell(db, "users[" + i + "].roleIds");
			if (!Strings.isBlank(roleIds)) {
				o.setRoles(dao.query(Role.class, Cnd.where("id", "in", roleIds.split(","))));
				dao.insertRelation(o, "roles");// 恢复用户和角色的关联
			}
		}

	}

}
